﻿/**
* 
* @author Chen
* @version 1.0
*
*/
angular.module("ng-unvs-template", ["ng-unvs-utils"])
.service("$template", ["$utils$text", "$http", "$compile", function ($text, $http, $compile) {
    var ret = function (path,template) {
        if (angular.isUndefined(path)) {
            throw ("path is undefined");
        }
        var me = ret;
        me.template = template;
        me.loadTemplatePath = template;
        me.path = path;
        me.loadPath = path;
        if (window.top.ngW8.$config.$noCache) {
            me.loadPath = path + "?t=" + (new Date()).getUTCMilliseconds();
        }
        me.$loadTemplate = function (callback) {
            var root = me.$getRootTemplate();
            if (!window.top.ngW8.unvsTemplate) {
                window.top.ngW8.unvsTemplate = {};
            }
            if (window.top.ngW8.unvsTemplate[me.template]) {
                me.$templateConfig = window.top.ngW8.unvsTemplate[me.template].config;
                callback(me);
            }
            else {
                window.top.ngW8.unvsTemplate[me.template] = {};
                $http.get(root + "/" + me.template)
                    .success(function (res) {

                        try {
                            var config = me.$getConfig(res);
                            window.top.ngW8.unvsTemplate[me.template].config = config;
                            me.$templateConfig = window.top.ngW8.unvsTemplate[me.template].config;
                            callback(me);

                            return me;
                        }
                        catch (ex) {
                            me.$error = ex;
                            if (me.onErrorCallback) {
                                me.onErrorCallback(me);
                            }
                        }


                    })
                    .then(function (res) {
                    },
                    function (error) {
                        me.$error = error;
                        if (me.onErrorCallback) {
                            me.onErrorCallback(me);
                        }
                    });
            }
        }

        me.$http = $http;

        me.$getConfig = function (strContent) {
            var txtBody = $text.$extract("<body>", "</body>", strContent);
            txtBody = $text.$clean("<!-- Visual Studio Browser Link -->", "<!-- End Browser Link -->", txtBody);
            txtBody = $text.$replace("\r\n", "", txtBody);
            var txtScript = $text.$extract("<script>", "</script>", txtBody);
            txtBody = txtBody.replace("<script>" + txtScript + "</script>", "");
            return {
                html: txtBody,
                script: txtScript
            };
        };
        me.$getRootTemplate = function () {
            if (!window.top.ngW8.$config.$loaderPath) {
                throw ("template path was not found, call $setRootTemplatePath of 'window.top.ngW8.$config'");
            }
            return window.top.ngW8.$config.$loaderPath;
        };
        me.$whenError = function (callback) {
            me.onErrorCallback = callback;
            return me;
        };
        me.$whenLoad = function (callback) {
            me.$whenLoadCallback = callback;
            return me;
        };
        me.$whenComplete = function (callback) {
            me.$whenCompleteCallback = callback;
            return me;
        };
        me.$load = function (callback) {
            me.$loadTemplate(function (sender) {
                if (!window.top.$pagesIntance) {
                    window.top.$pagesIntance = {};
                }
                if (!window.top.$pagesIntance[me.path]) {
                    window.top.$pagesIntance[me.path] = {
                        root: me.$getRootTemplate(),
                        path: path
                    };
                }
                if (!window.top.$pagesIntance[me.path].config) {
                    var root = me.$getRootTemplate();
                    $http.get(root + "/" + me.loadPath)
                         .success(function (res) {

                             try {
                                 var config = me.$getConfig(res);
                                 var ele = $("<div>" + me.$templateConfig.html + "</div>").appendTo("body");
                                 var fe = $("<div>" + config.html + "</div>").appendTo("body");
                                 ele.find("[container]").each(function (index, e) {
                                     var name = $(e).attr("container");
                                     var f = fe.find("[container='" + name + "']");
                                     if (f.length > 0) {
                                         $(e).html(f.html());
                                     }
                                 });
                                 config.html = ele.html();
                                 ele.remove();
                                 fe.remove();
                                 window.top.$pagesIntance[path].config = config;
                                 me.$instructions = window.top.$pagesIntance[path].config;

                                 callback(me)

                                 return me;
                             }
                             catch (ex) {
                                 me.$error = ex;
                                 if (me.onErrorCallback) {
                                     me.onErrorCallback(me);
                                 }
                             }


                         })
                         .then(function (res) {
                         },
                         function (error) {
                             me.$error = error;
                             if (me.onErrorCallback) {
                                 me.onErrorCallback(me);
                             }
                         });
                }
                else {
                    try {
                        me.$instructions = window.top.$pagesIntance[path].config;
                        callback(me);
                    }
                    catch (ex) {
                        if (me.onErrorCallback) {
                            me.onErrorCallback(ex);
                        }
                    }
                }
            });
        };
        me.$compile = function ($scope, callback) {

            var config = me.$instructions;
            var scope = $scope.$new(true);
            if (!window.top.ngW8.$rootAppScope) {
                window.top.ngW8.$rootAppScope = $scope.$root;

            }
            if (!$scope.$root.$scopeList) {
                $scope.$root.$scopeList = [];
            }
            $scope.$root.$scopeList.push(scope);
            scope.$$$ready = function (callback) {
                scope.$$$onReadyHandler = callback;
            };
            scope.$$$path = {
                full: me.$getRootTemplate() + "/" + me.path,
                root: me.$getRootTemplate(),
                page: me.path.replace(".html", ""),
                relative: me.path
            };


            var ele = $("<div>" + config.html + "</div>");
            try {
                $compile($(ele).contents())(scope);
                scope.$elements = ele.children();
                scope.$find = function (selector) {
                    return $(selector, scope.$elements);
                };
            }
            catch (ex) {
                if (me.onErrorCallback) {
                    me.onErrorCallback(ex);
                }
            }
            if (config.script &&
                   (config.script != null) &&
                   (config.script != "")) {

                try {
                    scope.$$$readyHandler = Function("", config.script);
                    scope.$$$readyHandler(scope);
                }
                catch (ex) {
                    if (me.onErrorCallback) {
                        me.onErrorCallback(ex);
                    }
                }
            }

            callback(scope, $(ele).children());
            if (scope.$$$onReadyHandler) {
                scope.$$$onReadyHandler(scope);
            };
            if (scope.$root.$$phase == null) {
                scope.$apply();
            }
        };
        me.$done = function (scope) {
            if (me.$whenLoadCallback) {
                me.$whenLoadCallback({
                    sender: me
                });
            }
            me.$load(function (sender) {
                me.$compile(scope, function (scope, ele) {
                    if (me.$whenCompleteCallback) {
                        me.$whenCompleteCallback({
                            sender: me,
                            scope: scope,
                            element: ele
                        });
                    }
                });
            });
        }
        return me;
    };
    return ret;

}]);